package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.commons.constants.CommonConstants;
import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.CourseAuditDto;
import com.xuecheng.commons.model.dto.CourseBaseDto;
import com.xuecheng.commons.model.dto.CourseDto;
import com.xuecheng.commons.model.dto.PageRequest;
import com.xuecheng.commons.model.vo.AuthInfo;
import com.xuecheng.commons.model.vo.PageResponseResult;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.utils.AuthInfoHolder;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.config.MinioProperties;
import com.xuecheng.content.config.MinioUtils;
import com.xuecheng.content.domain.CourseBase;
import com.xuecheng.content.domain.Teachplan;
import com.xuecheng.content.mappers.CourseBaseMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.xuecheng.content.service.TeachplanService;
import com.xuecheng.web.exceptions.BusinessException;
import io.minio.ObjectWriteResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * 课程基本信息 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-07-16
 */
@Service
@Slf4j
public class CourseBaseServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase> implements CourseBaseService {

    @Autowired
    private MinioProperties minioProperties;
    @Autowired
    private TeachplanService teachplanService;

    /**
     * @description: 分页查询课程数据业务
     * @param: [request, dto]
     * @return: com.xuecheng.commons.model.vo.ResponseResult
     * @author Keson
     * @date: 2022/7/16 17:54
     */
    @Override
    public ResponseResult courseList(PageRequest request, CourseDto dto) {
        //创建分页参数
        Page<CourseBase> courseBasePage = new Page<>(request.getPageNo(), request.getPageSize());
        //创建查询条件
        LambdaQueryWrapper<CourseBase> qw = new LambdaQueryWrapper<>();
        //课程名称
        String courseName = dto.getCourseName();
        if (!StringUtils.isEmpty(courseName)) {
            qw.like(CourseBase::getName, "%" + courseName + "%");
        }
        //课程审核状态
        String auditStatus = dto.getAuditStatus();
        if (!StringUtils.isEmpty(auditStatus)) {
            qw.eq(CourseBase::getAuditStatus, auditStatus);
        }
        //课程类型
        String teachmode = dto.getTeachmode();
        if (!StringUtils.isEmpty(teachmode)) {
            qw.eq(CourseBase::getTeachmode, teachmode);
        }
        //设置机构id
        //qw.eq(CourseBase::getCompanyId, AuthInfoHolder.getCompanyId());
        //分页查询
        IPage<CourseBase> iPage = this.page(courseBasePage, qw);
        //转化PageResponseResult
        return PageResponseResult.okResult(iPage.getTotal(), iPage.getRecords());
    }

    //上传封面图片
    @Override
    public ResponseResult upload(MultipartFile uploadFile) {
        String filePath = "/image/" +
                new SimpleDateFormat("yyyy/MM/dd/").format(new Date()) +
                UUID.randomUUID().toString() +
                uploadFile.getOriginalFilename();

        MinioUtils minioUtils = new MinioUtils(minioProperties.getEndpoint(),
                minioProperties.getBucket(),
                minioProperties.getAccessKey(),
                minioProperties.getSecretKey());
        try {
            ObjectWriteResponse objectWriteResponse = minioUtils.putObject(minioProperties.getBucket(),
                    uploadFile,
                    filePath,
                    "image/jpg");

        } catch (Exception e) {
            log.info("上传图片出现异常");
        }

        String urlPath = MinioUtils.getBasisUrl() + filePath;
        //String urlPath = minioProperties.getDomain()+"/"+minioProperties.getBucket()+filePath;
        return ResponseResult.okResult(urlPath);
    }

    //保存课程数据
    @Override
    @Transactional
    public ResponseResult saveCourseBase(CourseBaseDto dto) {

        //验证数据格式
        if (dto.getCharge() == null ||
                dto.getDescription() == null ||
                dto.getGrade() == null ||
                dto.getMt() == null ||
                dto.getName() == null ||
                dto.getObjectives() == null ||
                dto.getSt() == null ||
                dto.getTags() == null ||
                dto.getTeachmode() == null ||
                dto.getUsers() == null
        ) {
            throw new BusinessException(ErrorCode.PARAMSERROR);
        }


        //将传入的的数据转换成courseBase，并添加数据库空缺字段
        CourseBase courseBase = BeanHelper.copyProperties(dto, CourseBase.class);
        AuthInfo authInfo = AuthInfoHolder.getAuthInfo();
        courseBase.setCompanyName(authInfo.getCompanyName());
        courseBase.setAuditStatus(CourseConstants.AUDIT_UNPAST_STATUS);  //课程审核状态，未提交
        courseBase.setStatus(CommonConstants.USING_FLAG);   //删除状态，可以删除
        courseBase.setCreateDate(new Date());
        courseBase.setPlanNum(0);

        //判断是否添加成功，失败则创建异常
        boolean save = this.save(courseBase);
        if (!save) {
            throw new BusinessException(ErrorCode.ADDEERROR);
        }

        //初始化课程一级大纲
        Teachplan teachplan = new Teachplan();
        teachplan.setPname(courseBase.getName());
        teachplan.setParentid(0L);
        teachplan.setGrade(CourseConstants.FIRST_LEVEL);
        teachplan.setCourseId(courseBase.getId());
        teachplan.setStatus(CommonConstants.USING_FLAG);
        teachplan.setCreateDate(new Date());
        teachplan.setChangeDate(new Date());
        teachplan.setCompanyId(authInfo.getCompanyId());
        teachplanService.save(teachplan);


        //构造返回
        HashMap map = new HashMap<>();
        map.put("courseBaseId", courseBase.getId());

        return ResponseResult.okResult(map);
    }

    //更新课程数据
    @Override
    public ResponseResult updateCourseBase(CourseBaseDto dto) {
        //验证数据格式
        if (dto.getCharge() == null ||
                dto.getDescription() == null ||
                dto.getGrade() == null ||
                dto.getMt() == null ||
                dto.getName() == null ||
                dto.getObjectives() == null ||
                dto.getPrice() == null ||
                dto.getSt() == null ||
                dto.getTags() == null ||
                dto.getTeachmode() == null ||
                dto.getUsers() == null
        ) {
            throw new BusinessException(ErrorCode.PARAMSERROR);
        }

        //根据id查询课程数据
        CourseBase courseBase = this.getById(dto.getId());
        if (courseBase == null) {
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        //判断课程状态，是否可以修改课程
        String auditStatus = courseBase.getAuditStatus();
        if (!CourseConstants.AUDIT_DISPAST_STATUS.equals(auditStatus) &&
                !CourseConstants.AUDIT_UNPAST_STATUS.equals(auditStatus)) {
            throw new BusinessException(ErrorCode.UPDATEEERROR);
        }

        //修改课程
        CourseBase courseBase1 = BeanHelper.copyProperties(dto, CourseBase.class);
        boolean code = this.updateById(courseBase1);
        if (!code) {
            throw new BusinessException(ErrorCode.ADDEERROR);
        }

        //返回值
        Map map = new HashMap<>();
        map.put("courseBaseId", dto.getId());

        return ResponseResult.okResult(map);
    }

    //删除课程数据
    @Override
    public ResponseResult deleteCourseBase(String courseId) {
        //判断id非空
        if (courseId == null) {
            throw new BusinessException(ErrorCode.PARAMSERROR);
        }
        //对于已提交，已发布，已审核的课程不可删除
        //根据id查询数据，判断是否可以删除
        CourseBase courseBase = this.getById(courseId);
        //判断课程状态，是否可以删除课程
        String auditStatus = courseBase.getAuditStatus();
        if (CourseConstants.AUDIT_COMMIT_STATUS.equals(auditStatus) ||
                CourseConstants.AUDIT_PUBLISHED_STATUS.equals(auditStatus) ||
                CourseConstants.AUDIT_PASTED_STATUS.equals(auditStatus)) {
            throw new BusinessException(ErrorCode.DELETEERROR);
        }
        //删除课程
        LambdaQueryWrapper<CourseBase> qw = new LambdaQueryWrapper<>();
        qw.eq(CourseBase::getStatus, CommonConstants.USING_FLAG);
        qw.eq(CourseBase::getId, courseId);

        boolean b = this.remove(qw);
        if (!b) {
            throw new BusinessException(ErrorCode.ERROR);
        }

        return ResponseResult.okResult();
    }

    //提交审核
    @Override
    public ResponseResult commit(Long courseBaseId) {
        if (courseBaseId == null) {
            throw new BusinessException(ErrorCode.COMPANYERROR);
        }
        //查询数据
        CourseBase courseBase = this.getById(courseBaseId);
        if (courseBase == null) {
            throw new BusinessException(ErrorCode.NOTFOUND);
        }
        //设置课程状态为已提交
        courseBase.setAuditStatus(CourseConstants.AUDIT_COMMIT_STATUS);
        //更新
        boolean b = this.updateById(courseBase);
        if (!b) {
            throw new BusinessException(ErrorCode.ERROR);
        }

        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult approve(CourseAuditDto dto) {
        //根据id查询课程
        CourseBase courseBase = this.getById(dto.getCourseBaseId());
        if (courseBase == null) {
            throw new BusinessException(ErrorCode.COMPANYERROR);
        }
        //设置课程的状态字段
        courseBase.setAuditStatus(dto.getAuditStatus());
        //设置审核意见
        courseBase.setAuditMind(dto.getAuditMind());
        //设置审核时间
        courseBase.setAuditDate(new Date());
        //更新
        boolean b = this.updateById(courseBase);
        if (!b) {
            throw new BusinessException(ErrorCode.ERROR);
        }
        return ResponseResult.okResult(null);
    }
}
